/**
 *
 *  Util.Plot.SelfExpandingIntArray, V0.7
 *
 *  @author Michael Liljenstam
 *
 */

package SSF.Util.Plot;

import java.util.ArrayList;

/**
 *  Class to implement an "automatically extending Integer array" by 
 *  extending the Vector class. Overloads the set(...) method of the 
 *  Vector class to check whether or not the index is within the current 
 *  bounds of the array. If it's outside, the size of the array is increased 
 *  to fit in this new element. Also implements a new convenience method 
 *  "update(...)" for a "read-modify-write" operation on a element in the 
 *  array.
 *  <br><br>
 *
 *  NOTE: The methods supplied in this class are the only ones supported 
 *  for self-expanding arrays. Using other methods in the superclasses may 
 *  have "undefined" results - generally resulting in an "index out of bounds"
 *  exception.
 *
 *  @author Michael Liljenstam
 *
 *  $Id: SelfExpandingIntArray.java,v 1.8 2003/02/13 19:32:44 mili Exp $
 */

public class SelfExpandingIntArray extends ArrayList {

    // members

    long maxIndex = -1;

    // methods

    /**
     *  Sets the specified element (by index) to "element", and automatically
     *  increases the size of the array if necessary.
     */

    public void set(int index, int element) {
	if (index <= maxIndex) { // within current size?
	    set(index, new Integer(element)); // replace element
	} else { // beyond current size
	    // extend array
	    for (long i=maxIndex+1; i<index; i++) {
		add(null);
	    }
	    add(new Integer(element));
	    maxIndex = index;
	}
    }

    /**
     *  Returns the element at the specified position in the array.
     *  If this element has not been set, the value 0 will be returned
     *  but the element will not be created in the array.
     */

    public int getVal(int index) {
	if (index <= maxIndex) { // within current size?
	    Object elemObj = get(index);
	    if (elemObj != null) { // does the element exist?
		return ((Integer) elemObj).intValue(); // return the value
	    } else {
		return 0; // not set - return zero
	    }
	}
	return 0; // outside array - return zero
    }

    /**
     *  Update element at index by increment (+/-)
     */

    public void update(int index, int increment) {
	if (index <= maxIndex) { // within current size?
	    Object elemObj = get(index);
	    if (elemObj != null) { // does the element exist?
		int elem = ((Integer) elemObj).intValue();
		set(index, elem + increment);
	    } else {
		set(index, increment); // just set to increment
	    }
	} else { // beyond current size, just set to increment
	    set(index, increment);
	}
    }


    /**
     *  Update element by setting it to max(previous, new)
     */

    public void updateMax(int index, int newVal) {
	if (index <= maxIndex) { // within current size?
	    Object elemObj = get(index);
	    if (elemObj != null) { // does the element exist?
		int elem = ((Integer) elemObj).intValue();
		set(index, Math.max(elem, newVal));
	    } else {
		set(index, newVal); // just set to new value
	    }
	} else { // beyond current size, just set to new value
	    set(index, newVal);
	}
    }
}



/*=                                                                      =*/
/*=  Copyright (c) 1997--2000  SSF Research Network                      =*/
/*=                                                                      =*/
/*=  SSFNet is open source software, distributed under the GNU General   =*/
/*=  Public License.  See the file COPYING in the 'doc' subdirectory of  =*/
/*=  the SSFNet distribution, or http://www.fsf.org/copyleft/gpl.html    =*/
/*=                                                                      =*/
